package org.anyin.gitee.cloud.lib.core.web.serializer;

import com.fasterxml.jackson.core.JsonGenerator;
import com.fasterxml.jackson.databind.BeanProperty;
import com.fasterxml.jackson.databind.JsonMappingException;
import com.fasterxml.jackson.databind.JsonSerializer;
import com.fasterxml.jackson.databind.SerializerProvider;
import com.fasterxml.jackson.databind.ser.ContextualSerializer;
import lombok.SneakyThrows;
import lombok.extern.slf4j.Slf4j;
import org.anyin.gitee.cloud.lib.core.enums.BaseEnum;

import java.io.IOException;
import java.util.Arrays;
import java.util.Objects;
import java.util.Optional;

@Slf4j
public class StringAsDictSerializer extends JsonSerializer<String> implements ContextualSerializer {

    private DictAnnotation annotation;

    public StringAsDictSerializer(DictAnnotation annotation) {
        this.annotation = annotation;
    }

    public StringAsDictSerializer(){}

    @SneakyThrows
    @Override
    public void serialize(String value, JsonGenerator gen, SerializerProvider provider) throws IOException {
        if(annotation == null){
            log.error("dict annotation not found");
            return;
        }
        Class<? extends Enum> typeClazz = annotation.type();
        BaseEnum type = Arrays.stream(typeClazz.getEnumConstants()).map(t -> (BaseEnum) t)
                .filter(t -> Objects.equals(t.getCode(), value))
                .findAny().orElse(null);
        if(type == null){
            throw new DictSerializerException("value is error, not found enum type");
        }
        Dict dict = new Dict();
        dict.setCode(type.getCode());
        dict.setText(type.getText());
        gen.writeObject(dict);
    }

    @Override
    public JsonSerializer<?> createContextual(SerializerProvider prov, BeanProperty property) throws JsonMappingException {
        DictAnnotation annotation = Optional.ofNullable(property).map(item -> item.getAnnotation(DictAnnotation.class)).orElse(null);
        return new StringAsDictSerializer(annotation);
    }
}
